﻿namespace Cos.Core.Attributes
{
    using System;
    using System.Data;

    using Cos.Core.Service;

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, Inherited = true)]
    public class TransactionAttribute : InterceptorBaseAttribute, ITransactionAttribute
    {
        public TransactionAttribute()
        {
            this.IsolationLevel = IsolationLevel.ReadCommitted;
            this.Propagation = Propagation.Required;
            this.Timeout = -1;
            this.ReadOnly = false;
        }

        public TransactionAttribute(Propagation propagation)
            : this()
        {
            this.Propagation = propagation;
        }

        public TransactionAttribute(IsolationLevel isolationLevel)
            : this()
        {
            this.IsolationLevel = isolationLevel;
        }

        public TransactionAttribute(Propagation propagation, IsolationLevel isolationLevel)
            : this(propagation)
        {
            this.IsolationLevel = isolationLevel;
        }

        public Propagation Propagation { get; set; }

        public IsolationLevel IsolationLevel { get; set; }

        public int Timeout { get; set; }

        public bool ReadOnly { get; set; }

        public Type[] RollbackFor { get; set; }

        public Type[] NoRollbackFor { get; set; }

        public override void OnExecuting(object sender, InterceptorExecutingContextEventArg e)
        {
            var sessionFactory = ServiceLocator.Get<ISessionManager>();
            sessionFactory.Execute(this);
        }

        public override void OnError(object sender, InterceptorErrorContextEventArg e)
        {
            var sessionFactory = ServiceLocator.Get<ISessionManager>();
            sessionFactory.Error(this, e.Error);
        }

        public override void OnExecuted(object sender, InterceptorExecutedContextEventArg e)
        {
            var sessionFactory = ServiceLocator.Get<ISessionManager>();
            sessionFactory.Executed(this);
        }
    }
}
